package com.woniuxy.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniuxy.entity.Student;
import com.woniuxy.dao.StudentDao;
import com.woniuxy.entity.TestQuestions;
import com.woniuxy.service.StudentService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * (Student)表服务实现类
 *
 * @author zjx
 * @since 2021-05-14 19:41:33
 */
@Service("studentService")
public class StudentServiceImpl implements StudentService {
    @Resource
    private StudentDao studentDao;

    /**
     * 查看试卷
     * @param examId
     * @return
     */

    @Override
    public Map<String, Object> findExamPaper(int studentId, int examId) {
        Map<String, Object> examPaper = this.studentDao.findExamPaper(studentId,examId);
        System.out.println("整个查询结果"+examPaper);
        /**
        获取答题时长  theTestTime 分钟
         */
        //获取开始时间和结束时间的字符串
        String examBeginTime = String.valueOf(examPaper.get("examBeginTime"));
        String examDurationTime =String.valueOf( examPaper.get("examDurationTime"));
        DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            //将日期格式的字符串转换为日期类型
            Date examBeginTimeDate =(Date) simpleDateFormat.parse(examBeginTime);
            Date examDurationTimeDate = simpleDateFormat.parse(examDurationTime);
            //获取毫秒数,计算考试持续时间 得出分钟数
            long theTestTimeDate= examDurationTimeDate.getTime()-examBeginTimeDate.getTime();
            long theTestTime= theTestTimeDate/1000/60;
            //存入map
            examPaper.put("theTestTime",theTestTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        /**
         * 获取卷面总分
         * */
        //分别获取各种题型的总分,求和得出卷面总分
        //将object类型的数据转成String,在转成int,便于计算

        String[] strings = {"singleTotalScore","multipleTotalScore","judgeTotalScore",
                "fillBlankTotalScore","shortAnswerTotalScore",};
        int totalPoints=0;
        for (int i = 0; i < strings.length; i++) {
            Object o = examPaper.get(strings[i]);
            String s = String.valueOf(o);
             totalPoints += Integer.parseInt(s);
        }
        //求出卷面总分并且存储map 返回给前台
        examPaper.put("totalPoints",totalPoints);

        /**
         * 解析学生答案JSON数据
         */

        //通过键值对,获取JSON格式得学生答案object类型数据
        Object stringExamPaper = examPaper.get("studentAnswer");
        //将数据库查出来的JSON格式字符串,转换为JSON格式
        JSONObject jsonObj = JSONObject.fromObject(stringExamPaper);
        //获取所有题型对象 集合
        JSONArray subject = jsonObj.getJSONArray("subject");
        //获取错题字符串
        String wrongTopicNumber =(String) examPaper.get("wrongTopicNumber");
        //将错题字符串转换为字符串数组

        String[] wrongTopicNumberArr = wrongTopicNumber.split(",");
        for (int i = 0; i <wrongTopicNumberArr.length ; i++) {
            System.out.println("这个是错题集"+wrongTopicNumberArr[i]);

        }
        //遍历其中的所有题型对象集合
        for (int i = 0; i <subject.size() ; i++) {
            //拿到具体的题型对象 (中间多了一层)
            JSONObject o = (JSONObject) subject.get(i);
            Object subjectType = o.get("subjectType");
            String s1 = subjectType.toString();
            //创建一个集合,用于存储,每一道题的信息
            ArrayList<Object> list1 = new ArrayList<>();

            //通过键值对,拿到具体的题型对象
            if(s1.contains("单选题")){
                JSONArray list = o.getJSONArray("list");
                //遍历题型对象,拿到具体的每一道题的对象
                for (int j = 0; j < list.size(); j++) {
                    //拿到具体的题目的对象
                    JSONObject oo = (JSONObject) list.get(j);

                        //拿到具体每一道题的实际id
                        Integer subjectId = (Integer) oo.get("subjectId");

                        //拿到每一道题的实际学生答案答案
                        String studentAnswer = (String) oo.get("studentAnswer");

                        //拿到试题题库中相关的信息
                        Map<String, String> examPaperSon = this.studentDao.findExamPaperSon(subjectId);

                        //创建一个返回前端的试题对象
                        TestQuestions testQuestions = new TestQuestions();

                        //封装题号
                        testQuestions.setId(examPaperSon.get("testId"));
                        //封装题干
                        testQuestions.setQuestion(examPaperSon.get("testBody"));
                        //封装解析
                        testQuestions.setAnalysisContent(examPaperSon.get("analysisContent"));
                    //封装题目状态 0正确,1错误,2未答
                    for (int jj = 0; jj < wrongTopicNumberArr.length; jj++) {
                        String s = String.valueOf(examPaperSon.get("testId"));
                        if (wrongTopicNumberArr[jj].equals(s)) {
                            testQuestions.setStatus(1);
                            break;
                        }
                        if(studentAnswer==null ){
                            testQuestions.setStatus(2);
                            break;
                        }
                    }

                        //封装学生的答案选项
                    if(studentAnswer==null || studentAnswer=="" ){
                        testQuestions.setStatus(2);
                    }else if(studentAnswer.equals("1")){
                            testQuestions.setStudentOption("A");
                        }else if(studentAnswer.equals("2")){
                            testQuestions.setStudentOption("B");
                        }else if(studentAnswer.equals("3")){
                            testQuestions.setStudentOption("c");
                        }else if(studentAnswer.equals("4")){
                            testQuestions.setStudentOption("D");
                        }
                        //封装题目四个选项
                        String s = examPaperSon.get("options");
                        String[] split = s.split("@");

                        for (int k = 0; k < split.length; k++) {

                            String s2 = examPaperSon.get("isRight");
                            System.out.println("正确答案正确答案"+split[k]+"****"+s2);
                            //分别将各个选项设置到实体类中的选项属性中去
                            testQuestions.setAOption("A:"+split[0]);
                            testQuestions.setBOption("B:"+split[1]);
                            testQuestions.setCOption("C:"+split[2]);
                            testQuestions.setDOption("D:"+split[3]);


                            //得出正确选项的选项字母(A),并且设置到实体中的属性中去
                            if(s2.equals(split[k])){
                                if(k==0){
                                    testQuestions.setRightAnswers("A:"+s2);
                                }else if(k==1){
                                    testQuestions.setRightAnswers("B:"+s2);
                                }else if(k==2){
                                    testQuestions.setRightAnswers("C:"+s2);
                                }else if(k==3){
                                    testQuestions.setRightAnswers("D:"+s2);
                                }
                            }
                        }

                        list1.add(testQuestions);
                 }
                examPaper.put("singleTotal",list1);
                //通过键值对,拿到具体的题型对象
            } else  if(s1.contains("多选题")){
                    JSONArray list = o.getJSONArray("list");
                    //遍历题型对象,拿到具体的每一道题的对象
                    for (int j = 0; j < list.size(); j++) {
                        //拿到具体的题目的对象
                        JSONObject oo = (JSONObject) list.get(j);

                        //拿到具体每一道题的实际id
                        Integer subjectId = (Integer) oo.get("subjectId");

                        //拿到每一道题的实际答案(学生的)
                        List studentAnswer = (List) oo.get("studentAnswer");

                        //拿到试题题库中相关的信息
                        Map<String, String> examPaperSon = this.studentDao.findExamPaperSon(subjectId);
                        //创建一个返回前端的试题对象
                        TestQuestions testQuestions = new TestQuestions();
                        //封装题目状态 0正确,1错误,2未答
                        for (int jj = 0; jj < wrongTopicNumberArr.length; jj++) {
                            String s = String.valueOf(examPaperSon.get("testId"));
                            if (wrongTopicNumberArr[jj].equals(s)) {
                                testQuestions.setStatus(1);
                                break;
                            }
                            if(studentAnswer==null ){
                                testQuestions.setStatus(2);
                                break;
                            }
                        }

                        //封装题号
                        testQuestions.setId(examPaperSon.get("testId"));
                        //封装题干
                        testQuestions.setQuestion(examPaperSon.get("testBody"));
                        //封装解析
                        testQuestions.setAnalysisContent(examPaperSon.get("analysisContent"));

                        //封装题目四个选项
                        String s = examPaperSon.get("options");
                        String[] split = s.split("@");
                        //取出正确答案studentAnswer
                        String answer="";
                        String modelAnswer="";
                        for (int k = 0; k < split.length; k++) {

                            //分别将各个选项设置到实体类中的选项属性中去
                            testQuestions.setAOption("A:"+split[0]);
                            testQuestions.setBOption("B:"+split[1]);
                            testQuestions.setCOption("C:"+split[2]);
                            testQuestions.setDOption("D:"+split[3]);

                            for (int l = 0; l <studentAnswer.size() ; l++) {

                                if(studentAnswer.get(l).equals(k+1) && k==0){
                                    answer+="A";
                                }else if(studentAnswer.get(l).equals(k+1) && k==1){
                                    answer+="B";
                                }else if(studentAnswer.get(l).equals(k+1) && k==2){
                                    answer+="C";
                                }else if(studentAnswer.get(l).equals(k+1) && k==3){
                                    answer+="D";
                                }
                            }
                            String s2 = examPaperSon.get("isRight");
                            String[] split1 = s2.split("@");
                            for (int l = 0; l <split1.length ; l++) {
                                if (split1[l].equals(split[k]) && k==0) {
                                    modelAnswer+="A";
                                }else  if (split1[l].equals(split[k]) && k==1) {
                                    modelAnswer+="B";
                                }else if (split1[l].equals(split[k]) && k==2) {
                                    modelAnswer+="C";
                                }else if (split1[l].equals(split[k]) && k==3) {
                                    modelAnswer+="D";
                                }

                            }

                        }
                        //将学生答案转换成字符,写到实体中
                        testQuestions.setStudentOption(answer);
                        //将标准答案转换成字符,写到是体重
                        testQuestions.setRightAnswers(modelAnswer);
                        //将单个的题目写到list中
                        list1.add(testQuestions);
                    }
                    //将题目主题list写到map中
                    examPaper.put("multiple",list1);
                }else if(s1.contains("判断题")){
                JSONArray list = o.getJSONArray("list");
                //遍历题型对象,拿到具体的每一道题的对象
                for (int j = 0; j < list.size(); j++) {
                    //拿到具体的题目的对象
                    JSONObject oo = (JSONObject) list.get(j);

                    //拿到具体每一道题的实际id
                    Integer subjectId = (Integer) oo.get("subjectId");

                    //拿到每一道题的实际答案(学生的)0/1
                    Integer studentAnswer = (Integer) oo.get("studentAnswer");

                    //拿到试题题库中相关的信息
                    Map<String, String> examPaperSon = this.studentDao.findExamPaperSon(subjectId);

                    //创建一个返回前端的试题对象
                    TestQuestions testQuestions = new TestQuestions();
                    //封装题目状态 0正确,1错误,2未答
                    for (int jj = 0; jj < wrongTopicNumberArr.length; jj++) {
                        String s = String.valueOf(examPaperSon.get("testId"));
                        if (wrongTopicNumberArr[jj].equals(s)) {
                            testQuestions.setStatus(1);
                            break;
                        }
                        if(studentAnswer==null ){
                            testQuestions.setStatus(2);
                            break;
                        }
                    }
                    //封装题号
                    testQuestions.setId(examPaperSon.get("testId"));
                    //封装题干
                    testQuestions.setQuestion(examPaperSon.get("testBody"));
                    //封装解析
                    testQuestions.setAnalysisContent(examPaperSon.get("analysisContent"));
                    //封装判断题的答案
                    //拿到正确答案0/1
                    Object ss = examPaperSon.get("is_right");
                    Integer s=(Integer)ss;
                    //向实体类中写入标准答案  对/错
                    if(s==1){
                        testQuestions.setRightAnswers("对");
                    }else  {
                        testQuestions.setRightAnswers("错");
                    }
                    //向实体类中写入学生答案
                    if (studentAnswer==1) {
                        testQuestions.setStudentOption("对");
                    }else {
                        testQuestions.setStudentOption("错");
                    }
                    //将单个的题目写到list中
                    list1.add(testQuestions);
                }
                //将题目主题list写到map中
                examPaper.put("judgeTotal",list1);
            }else if( s1.contains("填空题") ){
                JSONArray list = o.getJSONArray("list");
                //遍历题型对象,拿到具体的每一道题的对象
                for (int j = 0; j < list.size(); j++) {
                    //拿到具体的题目的对象
                    JSONObject oo = (JSONObject) list.get(j);

                    //拿到具体每一道题的实际id
                    Integer subjectId = (Integer) oo.get("subjectId");

                    //拿到每一道题的实际答案(学生的)0/1
                    String studentAnswer = (String) oo.get("studentAnswer");

                    //拿到试题题库中相关的信息
                    Map<String, String> examPaperSon = this.studentDao.findExamPaperSon(subjectId);

                    //创建一个返回前端的试题对象
                    TestQuestions testQuestions = new TestQuestions();
                    //封装题目状态 0正确,1错误,2未答
                    for (int jj = 0; jj < wrongTopicNumberArr.length; jj++) {
                        String s = String.valueOf(examPaperSon.get("testId"));
                        if (wrongTopicNumberArr[jj].equals(s)) {
                            testQuestions.setStatus(1);
                            break;
                        }
                        if(studentAnswer==null ){
                            testQuestions.setStatus(2);
                            break;
                        }
                    }
                    //封装题号
                    testQuestions.setId(examPaperSon.get("testId"));
                    //封装题干
                    testQuestions.setQuestion(examPaperSon.get("testBody"));
                    //封装解析
                    testQuestions.setAnalysisContent(examPaperSon.get("analysisContent"));
                    //封装判断题的答案
                    //拿到判断题 标准答案 并写入到实体类中去
                    String ss = examPaperSon.get("isRight");
                    //标准答案 写入实体
                    testQuestions.setRightAnswers(ss);
                    //学生答案写入实体
                    testQuestions.setStudentOption(studentAnswer);
                    //将单个的题目写到list中
                    list1.add(testQuestions);
                }
                //将题目主题list写到map中
                examPaper.put("fillBlank",list1);
            }else if( s1.contains("简答题") ){

                JSONArray list = o.getJSONArray("list");
                //遍历题型对象,拿到具体的每一道题的对象
                for (int j = 0; j < list.size(); j++) {
                    //拿到具体的题目的对象
                    JSONObject oo = (JSONObject) list.get(j);

                    //拿到具体每一道题的实际id
                    Integer subjectId = (Integer) oo.get("subjectId");

                    //拿到每一道题的实际答案(学生的)0/1
                    String studentAnswer = (String) oo.get("studentAnswer");

                    //拿到试题题库中相关的信息
                    Map<String, String> examPaperSon = this.studentDao.findExamPaperSon(subjectId);

                    //创建一个返回前端的试题对象
                    TestQuestions testQuestions = new TestQuestions();
                    //封装题目状态 0正确,1错误,2未答
                    for (int jj = 0; jj < wrongTopicNumberArr.length; jj++) {
                        String s = String.valueOf(examPaperSon.get("testId"));
                        if (wrongTopicNumberArr[jj].equals(s)) {
                            testQuestions.setStatus(1);
                            break;
                        }
                        if(studentAnswer==null ){
                            testQuestions.setStatus(2);
                            break;
                        }
                    }
                    //封装题号
                    testQuestions.setId(examPaperSon.get("testId"));
                    //封装题干
                    testQuestions.setQuestion(examPaperSon.get("testBody"));
                    //封装解析
                    testQuestions.setAnalysisContent(examPaperSon.get("analysisContent"));
                    //封装判断题的答案
                    //拿到判断题 标准答案 并写入到实体类中去
                    String ss = examPaperSon.get("isRight");
                    //标准答案 写入实体
                    testQuestions.setRightAnswers(ss);
                    //学生答案写入实体
                    testQuestions.setStudentOption(studentAnswer);
                    //将单个的题目写到list中
                    list1.add(testQuestions);
                }
                //将题目主题list写到map中
                examPaper.put("shortAnswer",list1);
            }


            }



        return examPaper;
    }

    /**
     * 询查 一定时间段内  积分排行榜数据实现渲染
     * @param beginTime 开始时间
     *  @param overTime 结束时间
     *    @param startPage 起始页
     *   @param pageSize 页大小
     * @return List集合
     */
    @Override
    public PageInfo<Map<String, String>> leaderBoard(int startPage, int pageSize, String beginTime, String overTime) {
        List<Map<String, String>> leaderBoard = this.studentDao.leaderBoard(startPage, pageSize, beginTime, overTime);
        PageInfo<Map<String, String>> mapPageInfo = new PageInfo<>(leaderBoard);

        return mapPageInfo;
    }

    /**
     *  查看积分详情的多条数据
     * @param startPage 起始页码
     * @param pageSize  每页条数
     * @param
     * @return  pageInfo集合
     */
    @Override
    public PageInfo<Map<String, Object>> integralSubsidiary(int startPage, int pageSize, Integer id) {
            PageHelper.startPage(startPage,pageSize);
        List<Map<String, Object>> mapsIntegral = this.studentDao.integralSubsidiary(id);
        for (Map<String,Object> o :mapsIntegral) {
            if(o.get("grade").equals(1)){
                o.put("integralItem","考试成绩及格");
            }else if(o.get("grade").equals(2)){
                o.put("integralItem","考试成绩中等");
            }else if(o.get("grade").equals(3)){
                o.put("integralItem","考试成绩良好");
            }else if(o.get("grade").equals(3)){
                o.put("integralItem","考试成绩优秀");
            }

        }
        PageInfo<Map<String,Object>> pageInfo = new PageInfo(mapsIntegral);
        return pageInfo;
    }

    /**
     *  查看详情页   查询分页的多条数据
     * @param startPage 起始页码
     * @param pageSize  每页条数
     * @param
     * @return  pageInfo集合
     */

    @Override
    public PageInfo<Map<String, Object>> viewDetails(int startPage,int pageSize,int id) {
            PageHelper.startPage(startPage,pageSize);
        List<Map<String, Object>> maps = this.studentDao.viewDetails(id);
        //遍历集合,得到没一个map 每一条数据
        /*获取错题率*/
        for (Map<String,Object> o : maps) {
            //获取错题字符串
            String wrongTopicNumber = (String) o.get("wrongTopicNumber");
            //将错题字符数组通过逗号切割为字符串数组
            String[] split = wrongTopicNumber.split(",");
            //获取总题数
            BigDecimal testTotal = (BigDecimal) o.get("testTotal");
            //将数组长度(错题数)转换为BigDecimal类型
            BigDecimal bigDecimal = new BigDecimal(split.length);
            //计算出错题率  传入前台是记得乘以100  加上%
            BigDecimal rateOfWrongTopic=bigDecimal.divide(testTotal);
            //将错题率放回到map中
            o.put("rateOfWrongTopic", rateOfWrongTopic);
            //存入错题数
            o.put("WrongTopicNumber", split.length);
            //干掉map中的错题数组(因为已经存入了前端需要的错题数)
            o.remove("wrongTopicNumber");

            /*将数据库中的是否通过状态码,用字符串替换*/
            if(o.get("isPass") != null && o.get("isPass").equals(1)){
                o.put("isPass","通过");
            }else {
                o.put("isPass","不及格");
            }
            /**
             * 通过考试开始时间和结束时间,计算的出考试时长
             */
            //获取开始时间和结束时间
            Date examBeginTime = (Date) o.get("examBeginTime");
            Date examDurationTime = (Date) o.get("examDurationTime");
            //转换为毫秒数,便于计算(考试时长)examDurationTime
           long theTestTime= examDurationTime.getTime()-examBeginTime.getTime();
            //將考试分钟数存入map中
            o.put("theTestTime",theTestTime/1000/60);
        }

        PageInfo<Map<String, Object>> mapPageInfo1 = new PageInfo<>(maps);
        return mapPageInfo1;
    }


    /**
     * 员工档案  查询分页的多条数据
     * @param startPage 起始页码
     * @param pageSize  每页条数
     * @param
     * @return  pageInfo集合
     */
    @Override
    public PageInfo<Map<String, String>> fuzzySelectStudentTestIntegral(int startPage, int pageSize,String name) {
        PageHelper.startPage(startPage,pageSize);
        List<Map<String, String>> maps = this.studentDao.fuzzySelectStudentTestIntegral(name);
        PageInfo<Map<String, String>> mapPageInfo = new PageInfo<>(maps);
        return mapPageInfo;
    }


    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Student queryById(Integer id) {
        return this.studentDao.queryById(id);
    }
    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<Student> queryAllByLimit(int offset, int limit) {
        return this.studentDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param student 实例对象
     * @return 实例对象
     */
    @Override
    public Student insert(Student student) {
        this.studentDao.insert(student);
        return student;
    }

    /**
     * 修改数据
     *
     * @param student 实例对象
     * @return 实例对象
     */
    @Override
    public Student update(Student student) {
        this.studentDao.update(student);
        return this.queryById(student.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {

        return this.studentDao.deleteById(id) > 0;
    }
}
